package com.sdstc.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.IdCardNumberMethod;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.sdstc.modules.dao.*;
import com.sdstc.modules.eneity.*;
import com.sdstc.modules.query.AdjustQuery;
import com.sdstc.modules.query.ExportCustomQuery;
import com.sdstc.modules.service.OrgService;
import com.sdstc.modules.uitl.TreeUtils;
import com.sdstc.modules.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author ：wk
 * @date ：Created in 2022/10/21 13:51
 */
@Service
public class OrgServiceImpl implements OrgService {

    @Autowired
    private OrganPlanDao organPlanDao;

    @Autowired
    private OrgDao orgDao;

    @Autowired
    private PersonDao personDao;

    @Autowired
    private PersonPlanDao personPlanDao;

    @Autowired
    private OrgDetailYearDao orgDetailYearDao;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

//    private Map<String, List<String>> orgLevel2personOrg = new HashMap<>();
//
//    private Map<String, List<String>> orgLevel2personOrgDeputy = new HashMap<>();
//
//
//    {
//        orgLevel2personOrg.put(MechanismLevel.BUREAUDEPUTY.getCode(), Arrays.asList("C0","C2","C4","C6","C8"));
//
//        orgLevel2personOrgDeputy.put(MechanismLevel.BUREAUDEPUTY.getCode(), Arrays.asList("C1","C3","C5","C7","C9"));
//
//    }

    // 正职
    private final List<String> orgLevel2personOrg = Arrays.asList("C0","C2","C4","C6","C8","A0","A2","A3","A6","A8","A14");

    // 副职
    private final List<String> orgLevel2personOrgDeputy = Arrays.asList("C1","C3","C5","C7","C9","A1","A4","A5","A7","A9","A15");

    // 副局级高配
    private final List<String> highFJ = Arrays.asList("C0","C1","C2");

    // 正处级高配
    private final List<String> highZC = Arrays.asList("C0","C1","C2","C3","C4","C5");

    // 副处级高配
    private final List<String> highFC = Arrays.asList("C0","C1","C2","C3","C4","C5","C6");

    // 正科级高配
    private final List<String> highZK = Arrays.asList("C0","C1","C2","C3","C4","C5","C6","C7");

    // 副科级高配
    private final List<String> highFK = Arrays.asList("C0","C1","C2","C3","C4","C5","C6","C7","C8");

    // 股级高配
    private final List<String> highGJ = Arrays.asList("C0","C1","C2","C3","C4","C5","C6","C7","C8","C9");


    @Override
    @Transactional
    public OrgEntity saveOrg(OrgEntity orgEntity) {
        orgDao.insert(orgEntity);
        return orgEntity;
    }

    @Override
    @Transactional
    public OrgEntity updateOrg(OrgEntity orgEntity) {
        orgDao.updateById(orgEntity);
        return orgEntity;
    }

    @Override
    @Transactional
    public void deleteOrgById(String id) {
        recursiveDelete(id);
    }

    public void recursiveDelete(String id) {
        // 查询此节点下面的所有的子节点
        List<OrgEntity> list = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", id));
        // 若此节点下面没有子节点
        if (list.size() == 0) {
            orgDao.deleteById(id);

            // todo 人员怎么处理
        } else {
            for (OrgEntity orgEntity : list) {
                recursiveDelete(orgEntity.getId());
            }

            // todo 人员怎么处理
            orgDao.deleteById(id);
        }
    }

    @Override
    public List<OrgTreeVo> getOrgTree(String orgId) {
        // 所有的机构
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<OrgEntity>().orderByAsc("create_time"));
        return TreeUtils.getInstance().getOrgTree(orgId, orgEntities);
    }

    @Override
    public List<OrgTreeVo> getOrgSimpleTree(String orgId) {
        // 所有的机构
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<OrgEntity>().orderByAsc("create_time"));
        List<OrgTreeVo> orgTree = TreeUtils.getInstance().getOrgSimpleTree(orgId, orgEntities);
        //如果是济南市公安局：则统计内设人员数量
        if(orgTree.size()>0){
            orgTree.stream().forEach(x ->{
                recursion(x);
            });
        }
        return orgTree;
    }

    @Override
    public List<OrgTreeVo> getOrgChartList(String orgId) {
        // 所有的机构
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<OrgEntity>().orderByAsc("create_time"));
        List<OrgTreeVo> orgTree = TreeUtils.getInstance().getOrgChartTree(orgId, orgEntities);
        //如果是济南市公安局：则统计内设人员数量
        if(orgTree.size()>0){
            orgTree.stream().forEach(x ->{
                recursion(x);
            });
        }
        return orgTree;
    }



    @Override
    public List<OrgTreeVo> getOrgSimpleTreeSelect(String orgId) {
        // 所有的机构
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<OrgEntity>().orderByAsc("create_time"));
        List<OrgTreeVo> orgTree = TreeUtils.getInstance().getOrgTree(orgId, orgEntities);
        return orgTree;
    }

    @Override
    public void orgDistribute(List<OrgDistributeParamVo> list) {
        if(list.size()>0){
            for(OrgDistributeParamVo vo:list){
                orgDao.orgDistributeById(vo);
            }
        }
    }

    public void recursion(OrgTreeVo x){
        String id = x.getId();
        String pid = x.getPid();
        List<OrgEntity> new_List = new ArrayList<OrgEntity>();
        if(x.getChildren().size()>0){
            new_List = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", id));
        }else{
            new_List = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("id", id));
        }
        //预设编制 单列
        IntStream intStream1 = new_List.stream().mapToInt(OrgEntity::getOrganizationSingle);
        int sum1 = intStream1.reduce(0, Integer::sum);
        x.setOrganizationSingle(sum1);
        //预设编制 工勤
        IntStream intStream2 = new_List.stream().mapToInt(OrgEntity::getOrganizationWork);
        int sum2 = intStream2.reduce(0, Integer::sum);
        x.setOrganizationWork(sum2);
        //预设编制 行政
        IntStream intStream3 = new_List.stream().mapToInt(OrgEntity::getOrganizationAdmin);
        int sum3 = intStream3.reduce(0, Integer::sum);
        x.setOrganizationAdmin(sum3);
        //预设编制 事业
        IntStream intStream4 = new_List.stream().mapToInt(OrgEntity::getOrganizationSingle);
        int sum4 = intStream4.reduce(0, Integer::sum);
        x.setOrganizationCause(sum4);
        List<OrgTreeVo>  child_List = x.getChildren();
        if(child_List.size()>0){
            child_List.stream().forEach(y ->{
                recursion(y);
            });
        }
    }
    public void recursion2(OrgEntity x){
        String id = x.getId();
        String pid = x.getPid();
        List<OrgEntity> new_List = new ArrayList<OrgEntity>();
        new_List = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", id));
        if(new_List.size()==0){
            new_List = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("id", id));
        }
        //预设编制 单列
        IntStream intStream1 = new_List.stream().mapToInt(OrgEntity::getOrganizationSingle);
        int sum1 = intStream1.reduce(0, Integer::sum);
        x.setOrganizationSingle(sum1);
        //预设编制 工勤
        IntStream intStream2 = new_List.stream().mapToInt(OrgEntity::getOrganizationWork);
        int sum2 = intStream2.reduce(0, Integer::sum);
        x.setOrganizationWork(sum2);
        //预设编制 行政
        IntStream intStream3 = new_List.stream().mapToInt(OrgEntity::getOrganizationAdmin);
        int sum3 = intStream3.reduce(0, Integer::sum);
        x.setOrganizationAdmin(sum3);
        //预设编制 事业
        IntStream intStream4 = new_List.stream().mapToInt(OrgEntity::getOrganizationSingle);
        int sum4 = intStream4.reduce(0, Integer::sum);
        x.setOrganizationCause(sum4);
    }

    @Override
    public List<OrgTreeSelectVo> getOrgTreeSelectVo(String orgId){
        // 所有的机构
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<>());
        return TreeUtils.getInstance().getOrgTreeSelect(orgId, orgEntities);
    }


    public List<OrgTreeVo> loadChild(OrgTreeVo orgTreeVo, List<OrgTreeVo> orgTreeVos) {
        List<OrgTreeVo> children = new ArrayList<>();

        for (OrgTreeVo treeVo : orgTreeVos) {
            if (Objects.equals(treeVo.getPid(), orgTreeVo.getId())) {
                treeVo.setChildren(loadChild(treeVo, orgTreeVos));
                children.add(treeVo);
            }
        }

        return children;
    }

    @Override
    public AdjustMentVo getAdjustAfter(AdjustQuery adjustQuery) {

        // 所有的机构
        List<OrgEntity> allOrg = orgDao.selectList(new QueryWrapper<>());
        Map<String, OrgEntity> allOrg2Map = allOrg.stream().collect(Collectors.toMap(OrgEntity::getId, Function.identity()));

        AdjustMentVo adjustMentVo = new AdjustMentVo();

        // 调整前
        OrgAdjustVo orgAdjustFront = this.queryOrgDetail(adjustQuery.getOrgId());

        // 调整后
        OrgAdjustVo orgAdjustVoAfter = orgAdjustFront.deepClone();

        if (StringUtils.isBlank(adjustQuery.getTempVersionId()) && StringUtils.isBlank(adjustQuery.getPlanId())){
            adjustMentVo.setAdjustFront(orgAdjustFront);
            adjustMentVo.setAdjustAfter(orgAdjustVoAfter);
            return adjustMentVo;
        }

        List<PersonPlanEntity> personList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>()
                .eq(StringUtils.isNotBlank(adjustQuery.getTempVersionId()), "temp_version_id", adjustQuery.getTempVersionId())
                .eq(StringUtils.isNotBlank(adjustQuery.getPlanId()),"plan_id",adjustQuery.getPlanId())
                .isNotNull("version"));

        List<OrganPlanEntity> orgList = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>()
                .eq(StringUtils.isNotBlank(adjustQuery.getTempVersionId()), "temp_version_id", adjustQuery.getTempVersionId())
                .eq(StringUtils.isNotBlank(adjustQuery.getPlanId()),"plan_id",adjustQuery.getPlanId())
                .isNotNull("version"));

        // 构建内设、下设、派出、事业的编制总数,实际人数以及超编数
        buildOrgAndPeopleTotal(orgAdjustVoAfter,orgList,personList,allOrg2Map);

        // 构建总人数
        buildAllOrgAndPeople(orgAdjustVoAfter);

        // 调整内容
        buildChangeContent(adjustMentVo,orgList,personList,allOrg2Map);

        //创建时间
        adjustMentVo.setCreateTime(new Date());

        adjustMentVo.setAdjustFront(orgAdjustFront);
        adjustMentVo.setAdjustAfter(orgAdjustVoAfter);

        return adjustMentVo;
    }


    private void buildOrgAndPeopleTotal(OrgAdjustVo orgAdjustVoAfter, List<OrganPlanEntity> orgList, List<PersonPlanEntity> personList,Map<String, OrgEntity> allOrg2Map){

        List<OrgPeopleVo> typeDetail = orgAdjustVoAfter.getInternalList().getTypeDetail();
        List<OrgPeopleVo> consistsDetail = orgAdjustVoAfter.getConsistsList().getTypeDetail();
        List<OrgPeopleVo> sendDetail = orgAdjustVoAfter.getSendList().getTypeDetail();
        List<OrgPeopleVo> careerDetail = orgAdjustVoAfter.getCareerList().getTypeDetail();

        // 编制
        if (CollectionUtils.isNotEmpty(orgList)){
            for (OrganPlanEntity org : orgList) {

                doSetPrepareTotal(typeDetail,org);
                doSetPrepareTotal(consistsDetail,org);
                doSetPrepareTotal(sendDetail,org);
                doSetPrepareTotal(careerDetail,org);

            }
        }

        // 人数
        if (CollectionUtils.isNotEmpty(personList)){

            doSetActualNum(typeDetail,personList,allOrg2Map);
            doSetActualNum(consistsDetail,personList,allOrg2Map);
            doSetActualNum(sendDetail,personList,allOrg2Map);
            doSetActualNum(careerDetail,personList,allOrg2Map);

        }

        // 超编数
        doSetOverTotal(typeDetail);
        doSetOverTotal(consistsDetail);
        doSetOverTotal(sendDetail);
        doSetOverTotal(careerDetail);



    }

    private void doSetPrepareTotal(List<OrgPeopleVo> detail, OrganPlanEntity org){
        detail.forEach(o -> {
            if(Objects.equals(o.getOrgId(), org.getFromOrgId())){
                o.setPrepareTotal(o.getPrepareTotal() + org.getChangeNum());
            }

            //add 2023.11.14 start
            // 临时解决调整时选择子机构 编制总数不改变的问题
            // 根据fromOrgId获取到自身所在的级别(最高就是o.getOrgId的级别) 例如指挥部
            OrgEntity orgEntity = orgDao.selectById(org.getFromOrgId());
            if(orgEntity != null && Objects.equals(o.getOrgId(), orgEntity.getPid())){
                o.setPrepareTotal(o.getPrepareTotal() + org.getChangeNum());
            }
            //add 2023.11.14 end

            if (Objects.equals(o.getOrgId(), org.getToOrgId())){
                o.setPrepareTotal(o.getPrepareTotal() - org.getChangeNum());
            }
        });
    }

    private void doSetActualNum(List<OrgPeopleVo> detail, List<PersonPlanEntity> personList,Map<String, OrgEntity> allOrg2Map){
        Map<String, OrgPeopleVo> detail2Map = detail.stream().collect(Collectors.toMap(OrgPeopleVo::getOrgId, Function.identity()));

        for (PersonPlanEntity personPlanEntity : personList) {
            // 调走人员的单位 人数 - 1
            if (Objects.nonNull(detail2Map.get(personPlanEntity.getFromOrgId()))){
                detail2Map.get(personPlanEntity.getFromOrgId()).setActualNum(detail2Map.get(personPlanEntity.getFromOrgId()).getActualNum() - 1);
            }
            if (Objects.nonNull(detail2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid()))){
                detail2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid())
                        .setActualNum(detail2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid()).getActualNum() - 1);
            }
            if (Objects.nonNull(detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid()).getPid()))){
                detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid()).getPid())
                        .setActualNum(detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getFromOrgId()).getPid()).getPid()).getActualNum() - 1);
            }

            // 调入人员的单位 人数 + 1
            if (Objects.nonNull(detail2Map.get(personPlanEntity.getToOrgId()))){
                detail2Map.get(personPlanEntity.getToOrgId()).setActualNum(detail2Map.get(personPlanEntity.getToOrgId()).getActualNum() + 1);
            }
            if (Objects.nonNull(detail2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid()))){
                detail2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid())
                        .setActualNum(detail2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid()).getActualNum() + 1);
            }
            if (Objects.nonNull(detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid()).getPid()))){
                detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid()).getPid())
                        .setActualNum(detail2Map.get(allOrg2Map.get(allOrg2Map.get(personPlanEntity.getToOrgId()).getPid()).getPid()).getActualNum() + 1);
            }

        }
    }

    private void doSetOverTotal(List<OrgPeopleVo> detail){
        // 人数减编制数
        detail.forEach(op -> op.setOverTotal(op.getActualNum() - op.getPrepareTotal()));

    }

    private void buildAllOrgAndPeople(OrgAdjustVo orgAdjustVoAfter){

        OrgTypeVo internalList = orgAdjustVoAfter.getInternalList();
        OrgTypeVo consistsList = orgAdjustVoAfter.getConsistsList();
        OrgTypeVo sendList = orgAdjustVoAfter.getSendList();
        OrgTypeVo careerList = orgAdjustVoAfter.getCareerList();

        internalList.buildTotal(internalList,internalList.getTypeDetail());
        consistsList.buildTotal(consistsList, consistsList.getTypeDetail());
        sendList.buildTotal(sendList, sendList.getTypeDetail());
        careerList.buildTotal(careerList, careerList.getTypeDetail());

//        orgAdjustVoAfter.setPrepareTotal(internalList.getPrepareTotal() + consistsList.getPrepareTotal() + sendList.getPrepareTotal() + careerList.getPrepareTotal());

//        orgAdjustVoAfter.setActualNum(internalList.getActualNum() + consistsList.getActualNum() + sendList.getActualNum() + careerList.getActualNum());
        orgAdjustVoAfter.setOverTotal(orgAdjustVoAfter.getActualNum() - orgAdjustVoAfter.getPrepareTotal());
    }

    private void buildChangeContent(AdjustMentVo adjustMentVo, List<OrganPlanEntity> orgList, List<PersonPlanEntity> personList, Map<String, OrgEntity> allOrg2Map) {

        HashMap<Integer,List<Object>> content = new HashMap<>();

        Integer organMaxVersion = 0;
        Integer personMaxVersion = 0;

        if (CollectionUtils.isNotEmpty(orgList)){
            organMaxVersion = orgList.size() > 1 ?
                    orgList.stream().sorted(((o1, o2) -> o2.getVersion().compareTo(o1.getVersion()))).collect(Collectors.toList()).get(0).getVersion() : orgList.get(0).getVersion();
        }

        if (CollectionUtils.isNotEmpty(personList)){
            personMaxVersion = personList.size() > 1 ?
                    personList.stream().sorted(((o1, o2) -> o2.getVersion().compareTo(o1.getVersion()))).collect(Collectors.toList()).get(0).getVersion() : personList.get(0).getVersion();
        }

        int maxVersion = organMaxVersion > personMaxVersion ? organMaxVersion : personMaxVersion;

        if (maxVersion == 0){
            return;
        }
        // 机构调整信息
        if (CollectionUtils.isNotEmpty(orgList)){
            Map<Integer, List<OrganPlanEntity>> organVersion2Map = orgList.stream().collect(Collectors.groupingBy(OrganPlanEntity::getVersion));
            for (int i = 1; i <= maxVersion; i++){
                List<OrganPlanEntity> organPlanEntities = Objects.nonNull(organVersion2Map.get(i)) ? organVersion2Map.get(i) : new ArrayList<>();
                List<Object> orgContent = new ArrayList<>();
                for (OrganPlanEntity org : organPlanEntities) {
                    OrganRecordVo organRecordVo = new OrganRecordVo();
                    int changeInt = org.getChangeNum();
                    organRecordVo.setOrganType(OrganType.organTypeOf(org.getOrganType()).getInfo());
                    organRecordVo.setChangeNum(Math.abs(changeInt));
                    if (changeInt > 0){

                        if (Objects.nonNull(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid())) &&
                                !Objects.equals(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid()).getOrgLevel(), MechanismLevel.BUREAUDEPUTY.getCode())){

                            organRecordVo.setFromOrgName(allOrg2Map.get(allOrg2Map.get(org.getToOrgId()).getPid()).getOrgName() + "-" + allOrg2Map.get(org.getToOrgId()).getOrgName());
                            organRecordVo.setToOrgName(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid()).getOrgName() + "-" + allOrg2Map.get(org.getFromOrgId()).getOrgName());

                        }else {

                            organRecordVo.setFromOrgName(allOrg2Map.get(org.getToOrgId()).getOrgName());
                            organRecordVo.setToOrgName(allOrg2Map.get(org.getFromOrgId()).getOrgName());

                        }

                    }else {
                        if (Objects.nonNull(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid())) &&
                                !Objects.equals(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid()).getOrgLevel(), MechanismLevel.BUREAUDEPUTY.getCode())){

                            organRecordVo.setFromOrgName(allOrg2Map.get(allOrg2Map.get(org.getFromOrgId()).getPid()).getOrgName() + "-" + allOrg2Map.get(org.getFromOrgId()).getOrgName());
                            organRecordVo.setToOrgName(allOrg2Map.get(allOrg2Map.get(org.getToOrgId()).getPid()).getOrgName() + "-" +  allOrg2Map.get(org.getToOrgId()).getOrgName());

                        }else {

                            organRecordVo.setFromOrgName(allOrg2Map.get(org.getFromOrgId()).getOrgName());
                            organRecordVo.setToOrgName(allOrg2Map.get(org.getToOrgId()).getOrgName());

                        }

                    }
                    orgContent.add(organRecordVo);
                }
                if (CollectionUtils.isNotEmpty(orgContent)){
                    content.put(i,orgContent);
                }
            }

        }

        // 人员调整内容
        if (CollectionUtils.isNotEmpty(personList)){
            Map<Integer, List<PersonPlanEntity>> personVersion2Map = personList.stream().collect(Collectors.groupingBy(PersonPlanEntity::getVersion));
            for (int i = 1;i <= maxVersion; i++){
                Map<String, List<PersonPlanEntity>> person2Map = Objects.nonNull(personVersion2Map.get(i)) ?
                        personVersion2Map.get(i).stream().collect(Collectors.groupingBy(o -> o.getFromOrgId() + "_" + o.getToOrgId())) : new HashMap<>();
                List<Object> peopleContent = new ArrayList<>();
                for (Map.Entry<String, List<PersonPlanEntity>> stringListEntry : person2Map.entrySet()) {
                    PersonRecordVo personRecordVo = new PersonRecordVo();
                    List<PersonPlanEntity> value = stringListEntry.getValue();
                    personRecordVo.setChangeNum(value.size());
                    List<String> personIds = value.stream().map(PersonPlanEntity::getPersonId).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(personIds)){
                        personRecordVo.setPersonList(personDao.selectList(new QueryWrapper<PersonEntity>().in("id",personIds)));
                    }
                    if (!Objects.equals(allOrg2Map.get(allOrg2Map.get(stringListEntry.getKey().split("_")[0]).getPid()).getOrgLevel(), MechanismLevel.BUREAUDEPUTY.getCode())){

                        personRecordVo.setFromOrgName(allOrg2Map.get(allOrg2Map.get(stringListEntry.getKey().split("_")[0]).getPid()).getOrgName() + "-" + allOrg2Map.get(stringListEntry.getKey().split("_")[0]).getOrgName());
                        personRecordVo.setToOrgName(allOrg2Map.get(stringListEntry.getKey().split("_")[1]).getOrgName());

                    }else {

                        personRecordVo.setFromOrgName(allOrg2Map.get(stringListEntry.getKey().split("_")[0]).getOrgName());
                        personRecordVo.setToOrgName(allOrg2Map.get(stringListEntry.getKey().split("_")[1]).getOrgName());

                    }
                    peopleContent.add(personRecordVo);
                }
                if (CollectionUtils.isNotEmpty(peopleContent)){
                    if (CollectionUtils.isNotEmpty(content.get(i))){
                        content.get(i).addAll(peopleContent);
                    }else {
                        content.put(i,peopleContent);
                    }
                }
            }


        }

        adjustMentVo.setRecord(content);
    }

    // 获取总览浮动窗口的详情
    @Override
    public OrgDetailVo getOrgDetailView(String orgId) {


        OrgDetailVo orgDetailVo = new OrgDetailVo();
        List<OrgEntity> orgEntities = orgDao.selectList(new QueryWrapper<>());
        Map<String, OrgEntity> allOrg2Map = orgEntities.stream().collect(Collectors.toMap(OrgEntity::getId, Function.identity()));
        // 获取改机构下面的所有的机构
        List<OrgTreeVo> orgList = TreeUtils.getAllOrg(orgId, orgEntities);

        // 该机构
        OrgEntity orgEntityItself = allOrg2Map.get(orgId);
        if(orgEntityItself != null){
            recursion2(orgEntityItself);
        }
        orgDetailVo.setOrgName(orgEntityItself.getOrgName());
        orgDetailVo.setOrgLevel(orgEntityItself.getOrgLevel());
        orgDetailVo.setOrgType(orgEntityItself.getOrgType());


        List<OrgTreeVo> orgTreeItselfList = new ArrayList<>();

        orgList.forEach(o -> {
            try {
                orgTreeItselfList.add(o.clone());
            }catch (CloneNotSupportedException e){
                e.printStackTrace();
            }
        });

        orgTreeItselfList.add(OrgTreeVo.getInstance(orgEntityItself));

        //获取该机构下面以及该机构的所有人员
        List<String> orgItselfIds =
                orgTreeItselfList.stream().map(OrgTreeVo::getId).distinct().collect(Collectors.toList());
        List<PersonEntity> personItSelfEntities =
                personDao.selectList(Wrappers.<PersonEntity>query().in("org_id", orgItselfIds).in("status",Arrays.asList(PersonStatus.OK.getCode(),PersonStatus.HIGH.getCode())));

        // 人员去重
        Map<Object, Boolean> map = new HashMap<>();
        personItSelfEntities = personItSelfEntities.stream().filter(p -> map.putIfAbsent(p.getPoliceNo() + p.getIdentityNo(), Boolean.TRUE) == null).collect(Collectors.toList());


        orgDetailVo.setRealPerson(personItSelfEntities.size());
        //  构建编制及实有
        buildOrgan(personItSelfEntities, orgDetailVo,orgEntityItself);

        // 构建机构及设置
        buildMechanism(orgList, orgDetailVo);

        // 构建职数及配备
        buildPositions(personItSelfEntities, orgDetailVo,orgEntityItself,allOrg2Map);

        // 实际编制数
//        orgDetailVo.setRealOrgan(orgDetailVo.getOrganizationAdmin().getExisting() + orgDetailVo.getOrganizationSingle().getExisting() +
//                orgDetailVo.getOrganizationWork().getExisting() + orgDetailVo.getOrganizationCause().getExisting());
        orgDetailVo.setRealOrgan(orgDetailVo.getOrganizationAdmin().getPlan() + orgDetailVo.getOrganizationSingle().getPlan() +
                orgDetailVo.getOrganizationWork().getPlan() + orgDetailVo.getOrganizationCause().getPlan());
        // 高配人数
        buildHighPerson(orgEntityItself,orgDetailVo);
        return orgDetailVo;
    }

    private void buildOrgItself(OrgEntity orgEntityItself, OrgDetailVo orgDetailVo){

        OrgDetailVo.Organization organizationAdmin = orgDetailVo.getOrganizationAdmin();
        organizationAdmin.setPlan(Objects.nonNull(orgEntityItself.getOrganizationAdmin()) ? orgEntityItself.getOrganizationAdmin() : 0);
        OrgDetailVo.Organization organizationSingle = orgDetailVo.getOrganizationSingle();
        organizationSingle.setPlan(Objects.nonNull(orgEntityItself.getOrganizationSingle()) ? orgEntityItself.getOrganizationSingle() : 0);
        OrgDetailVo.Organization organizationCause = orgDetailVo.getOrganizationCause();
        organizationCause.setPlan(Objects.nonNull(orgEntityItself.getOrganizationCause()) ? orgEntityItself.getOrganizationCause() : 0);
        OrgDetailVo.Organization organizationWork = orgDetailVo.getOrganizationWork();
        organizationWork.setPlan(Objects.nonNull(orgEntityItself.getOrganizationWork()) ? orgEntityItself.getOrganizationWork() : 0);

        OrgDetailVo.Positions departmentLead = orgDetailVo.getDepartmentLead();
        departmentLead.setPlan(Objects.nonNull(orgEntityItself.getDepartmentLead()) ? orgEntityItself.getDepartmentLead() : 0);
        OrgDetailVo.Positions departmentLeadDeputy = orgDetailVo.getDepartmentLeadDeputy();
        departmentLeadDeputy.setPlan(Objects.nonNull(orgEntityItself.getDepartmentLeadDeputy()) ? orgEntityItself.getDepartmentLeadDeputy() : 0);
        OrgDetailVo.Positions sameDepartmentLead = orgDetailVo.getSameDepartmentLead();
        sameDepartmentLead.setPlan(Objects.nonNull(orgEntityItself.getSameDepartmentLead()) ? orgEntityItself.getSameDepartmentLead() : 0);
        OrgDetailVo.Positions internalLead = orgDetailVo.getInternalLead();
        internalLead.setPlan(Objects.nonNull(orgEntityItself.getInternalLead()) ? orgEntityItself.getInternalLead() : 0);
        OrgDetailVo.Positions internalLeadDeputy = orgDetailVo.getInternalLeadDeputy();
        internalLeadDeputy.setPlan(Objects.nonNull(orgEntityItself.getInternalLeadDeputy()) ? orgEntityItself.getInternalLeadDeputy() : 0);
        OrgDetailVo.Positions sameInternalLead = orgDetailVo.getSameInternalLead();
        sameInternalLead.setPlan(Objects.nonNull(orgEntityItself.getSameInternalLead()) ? orgEntityItself.getSameInternalLead() : 0);

    }

    private void buildHighPerson(OrgEntity orgEntityItself, OrgDetailVo orgDetailVo) {
        String orgLevel = orgEntityItself.getOrgLevel();

        // 根据人的状态为高配查询
        if (Objects.nonNull(orgLevel)){
            List<PersonEntity> personEntityList = personDao.selectList(new QueryWrapper<PersonEntity>().eq("org_id", orgEntityItself.getId()));
            orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> Objects.equals(p.getStatus(), PersonStatus.HIGH.getCode())).count());
        }

        // 根据人的级别与人所在机构的级别查询
//        if (Objects.nonNull(orgLevel)){
//            List<PersonEntity> personEntityList = personDao.selectList(new QueryWrapper<PersonEntity>().eq("org_id", orgEntityItself.getId()));
//            if (Objects.equals(orgLevel,MechanismLevel.BUREAUDEPUTY.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highFJ.contains(p.getPostSmallCateCode())).count());
//            }else if (Objects.equals(orgLevel,MechanismLevel.DIVISION.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highZC.contains(p.getPostSmallCateCode())).count());
//            }else if (Objects.equals(orgLevel,MechanismLevel.DIVISIONDEPUTY.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highFC.contains(p.getPostSmallCateCode())).count());
//            }else if (Objects.equals(orgLevel,MechanismLevel.DEPARTMENT.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highZK.contains(p.getPostSmallCateCode())).count());
//            }else if (Objects.equals(orgLevel,MechanismLevel.DEPARTMENTDEPUTY.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highFK.contains(p.getPostSmallCateCode())).count());
//            }else if (Objects.equals(orgLevel,MechanismLevel.INTERNALGROUP.getCode())){
//                orgDetailVo.setHighPersonCount((int) personEntityList.stream().filter(p -> highGJ.contains(p.getPostSmallCateCode())).count());
//            }
//        }

    }


    private void buildPositions(List<PersonEntity> personItSelfEntities, OrgDetailVo orgDetailVo,OrgEntity orgEntityItself,Map<String, OrgEntity> allOrg2Map) {


        //过滤掉小类为空的
        List<PersonEntity> personListNotNullSmall = personItSelfEntities.stream().filter(p -> Objects.nonNull(p.getPostSmallCateCode())).collect(Collectors.toList());

        // 部门领导正职
        orgDetailVo.setDepartmentLead(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getDepartmentLead()) ? orgEntityItself.getDepartmentLead() : 0,
                (int) personListNotNullSmall.stream().filter(p -> Objects.equals(p.getLeaderType(), LeaderType.DepartmentPrincipal.getCode())).count()
        ));

        // 部门领导副职
        orgDetailVo.setDepartmentLeadDeputy(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getDepartmentLeadDeputy()) ? orgEntityItself.getDepartmentLeadDeputy() : 0,
                (int) personListNotNullSmall.stream().filter(p -> Objects.equals(p.getLeaderType(), LeaderType.DepartmentDeputy.getCode())).count()
        ));

        //与部门领导同级别的其他领导
        orgDetailVo.setSameDepartmentLead(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getSameDepartmentLead()) ? orgEntityItself.getSameDepartmentLead() : 0,
                (int) personItSelfEntities.stream().filter(p -> Objects.equals(p.getLeaderType(), LeaderType.DepartmentOther.getCode())).count()
        ));

        // 内设机构领导正职
        orgDetailVo.setInternalLead(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getInternalLead()) ? orgEntityItself.getInternalLead() : 0,
                (int) personListNotNullSmall.stream()
                        .filter(p -> Objects.equals(p.getLeaderType(), LeaderType.InternalPrincipal.getCode())).count()
        ));
        // 内设机构领导副职
        orgDetailVo.setInternalLeadDeputy(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getInternalLeadDeputy()) ? orgEntityItself.getInternalLeadDeputy() : 0,
                (int) personListNotNullSmall.stream()
                        .filter(p -> Objects.equals(p.getLeaderType(), LeaderType.InternalDeputy.getCode())).count()
        ));

        // 与内设机构领导同级别的其他领导
        orgDetailVo.setSameInternalLead(new OrgDetailVo.Positions(
                Objects.nonNull(orgEntityItself.getSameInternalLead()) ? orgEntityItself.getSameInternalLead() : 0,
                (int) personItSelfEntities.stream().filter(p -> Objects.equals(p.getLeaderType(), LeaderType.InternalOther.getCode())).count()
        ));



    }

    private void buildMechanism(List<OrgTreeVo> orgList, OrgDetailVo orgDetailVo) {

        orgList = orgList.stream().filter(o -> (!Objects.equals(o.getOrgName(), "部门领导") && !Objects.equals(o.getOrgName(), "分局领导"))).collect(Collectors.toList());

        Map<String, List<OrgTreeVo>> level2list = orgList.stream().filter(o -> Objects.nonNull(o.getOrgLevel())).collect(Collectors.groupingBy(OrgTreeVo::getOrgLevel));


        // 副局
        orgDetailVo.setBureauDeputy(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.BUREAUDEPUTY.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.BUREAUDEPUTY.getCode())) : new OrgDetailVo.Mechanism());

        // 处
        orgDetailVo.setDivision(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.DIVISION.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.DIVISION.getCode())) : new OrgDetailVo.Mechanism());

        // 副处
        orgDetailVo.setDivisionDeputy(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.DIVISIONDEPUTY.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.DIVISIONDEPUTY.getCode())) : new OrgDetailVo.Mechanism());

        // 科
        orgDetailVo.setDepartment(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.DEPARTMENT.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.DEPARTMENT.getCode())) : new OrgDetailVo.Mechanism());

        // 副科
        orgDetailVo.setDepartmentDeputy(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.DEPARTMENTDEPUTY.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.DEPARTMENTDEPUTY.getCode())) : new OrgDetailVo.Mechanism());

        // 股
        orgDetailVo.setGroup(CollectionUtils.isNotEmpty(level2list.get(MechanismLevel.INTERNALGROUP.getCode())) ?
                OrgDetailVo.Mechanism.buildMechanism(level2list.get(MechanismLevel.INTERNALGROUP.getCode())) : new OrgDetailVo.Mechanism());


    }

    private void buildOrgan(List<PersonEntity> personItSelfEntities, OrgDetailVo orgDetailVo,OrgEntity orgEntityItself) {

        Map<String, List<PersonEntity>> organ2Map =
                personItSelfEntities.stream().filter(p -> Objects.nonNull(p.getPostBigCateCode())).collect(Collectors.groupingBy(PersonEntity::getPostBigCateCode));

        // 设置 行政信息
        orgDetailVo.setOrganizationAdmin(OrgDetailVo.Organization.buildInstance(orgEntityItself.getOrganizationAdmin(),
                CollectionUtils.isNotEmpty(organ2Map.get(OrganType.ADMIN.getCode())) ? organ2Map.get(OrganType.ADMIN.getCode()).size() : 0));

        // 设置 单列信息
        orgDetailVo.setOrganizationSingle(OrgDetailVo.Organization.buildInstance(orgEntityItself.getOrganizationSingle(),
                CollectionUtils.isNotEmpty(organ2Map.get(OrganType.SINGLE.getCode())) ? organ2Map.get(OrganType.SINGLE.getCode()).size() : 0));

        // 设置 工勤信息
        orgDetailVo.setOrganizationWork(OrgDetailVo.Organization.buildInstance(orgEntityItself.getOrganizationWork(),
                CollectionUtils.isNotEmpty(organ2Map.get(OrganType.WORK.getCode())) ? organ2Map.get(OrganType.WORK.getCode()).size() : 0));


        // 设置 事业信息
        orgDetailVo.setOrganizationCause(OrgDetailVo.Organization.buildInstance(orgEntityItself.getOrganizationCause(),
                CollectionUtils.isNotEmpty(organ2Map.get(OrganType.CAUSE.getCode())) ? organ2Map.get(OrganType.CAUSE.getCode()).size() : 0));

    }

    //获取架构调整模块各机构类型机构的编制、人数、超编数量
    @Override
    public OrgAdjustVo queryOrgDetail(String orgId) {

        OrgAdjustVo orgAdjustVo = new OrgAdjustVo();
        List<OrgEntity> internals = new ArrayList<>();
        List<OrgEntity> consists = new ArrayList<>();
        List<OrgEntity> sends = new ArrayList<>();
        List<OrgEntity> careers = new ArrayList<>();
        OrgTypeVo internalList = new OrgTypeVo();
        OrgTypeVo consistsList = new OrgTypeVo();
        OrgTypeVo sendList = new OrgTypeVo();
        OrgTypeVo careerList = new OrgTypeVo();

        Map<String,List<OrgEntity>> orgEntityMap = new HashMap<>();

        OrgEntity orgEntity = orgDao.selectById(orgId);//市公安局
        List<OrgEntity> org = orgDao.selectList(new QueryWrapper<OrgEntity>().lambda().eq(OrgEntity::getPid, orgId));//市公安局下属公安局

        int prepareTotal = (Objects.isNull(orgEntity.getOrganizationAdmin()) ? 0 : orgEntity.getOrganizationAdmin())
                            + (Objects.isNull(orgEntity.getOrganizationWork()) ? 0 : orgEntity.getOrganizationWork())
                            + (Objects.isNull(orgEntity.getOrganizationSingle()) ? 0 : orgEntity.getOrganizationSingle())
                            + (Objects.isNull(orgEntity.getOrganizationCause()) ? 0 : orgEntity.getOrganizationCause());

        // 正常人员与高配人员
        List<PersonEntity> okAndHighPerson = personDao.selectList(new QueryWrapper<PersonEntity>().in("status", Arrays.asList(PersonStatus.OK.getCode(), PersonStatus.HIGH.getCode())));

        okAndHighPerson = okAndHighPerson.stream().filter(o -> Objects.nonNull(o.getOrgId())).collect(Collectors.toList());

        // 人员 根据orgId分组
        Map<String, List<PersonEntity>> orgId2Map = okAndHighPerson.stream().collect(Collectors.groupingBy(PersonEntity::getOrgId));

        // 机构 根据pid分组
        List<OrgEntity> orgEntityList = orgDao.selectList(new QueryWrapper<>());
        Map<String, List<OrgEntity>> pid2Map = orgEntityList.stream().collect(Collectors.groupingBy(OrgEntity::getPid));

        //当前机构人数
        int actualNum = getOrgPersonTotal(orgId,orgId2Map,pid2Map);
//        for (OrgEntity entity : org) {
//            actualNum = actualNum+personDao.selectList(new QueryWrapper<PersonEntity>().eq("org_id",entity.getId())).size();
//        }

        //按照OrgType分类
        for (OrgEntity entity : org) {//区公安局
            if (StringUtils.isNotBlank(entity.getOrgType())){
                if (entity.getOrgType().equals(MechanismType.INTERNAL.getCode())){
                    internals.add(entity);
                }else if(entity.getOrgType().equals(MechanismType.UNDER.getCode())){
                    consists.add(entity);
                }else if (entity.getOrgType().equals(MechanismType.DISPATCH.getCode())){
                    sends.add(entity);
                }else if (entity.getOrgType().equals(MechanismType.CAUSE.getCode())){
                    careers.add(entity);
                }
            }
        }
        orgEntityMap.put("internals",internals);
        orgEntityMap.put("consists",consists);
        orgEntityMap.put("sends",sends);
        orgEntityMap.put("careers",careers);

        for(String key : orgEntityMap.keySet()){//根据类型分组遍历区公安局集合
            int internalTotal = 0;//各分组中预设机构总数
            int internalPeople = 0;//各分组中实际人数
            List<OrgPeopleVo> internalDetail = new ArrayList<>();
            for (OrgEntity internal : orgEntityMap.get(key)) {//根据类型分组遍历区公安局
                int total = (Objects.isNull(internal.getOrganizationAdmin()) ? 0 : internal.getOrganizationAdmin())
                            + (Objects.isNull(internal.getOrganizationWork()) ? 0 : internal.getOrganizationWork())
                            + (Objects.isNull(internal.getOrganizationSingle()) ? 0 : internal.getOrganizationSingle())
                            + (Objects.isNull(internal.getOrganizationCause()) ? 0 : internal.getOrganizationCause());
//                int actTotal = personDao.selectList(new QueryWrapper<PersonEntity>().eq("org_id",internal.getId())).size();
                int actTotal = getOrgPersonTotal(internal.getId(), orgId2Map, pid2Map);
                internalTotal = internalTotal + total;
                internalPeople = internalPeople + actTotal;
                OrgPeopleVo orgPeopleVo = new OrgPeopleVo();
                orgPeopleVo.setPrepareTotal(total);
                orgPeopleVo.setActualNum(actTotal);
                orgPeopleVo.setOverTotal(actTotal-total);
                orgPeopleVo.setOrgName(internal.getOrgName());
                orgPeopleVo.setOrgId(internal.getId());
                orgPeopleVo.setOrgType(internal.getOrgType());
                internalDetail.add(orgPeopleVo);
            }
            if (key.equals("internals")){
                internalList.setPrepareTotal(internalTotal);
                internalList.setActualNum(internalPeople);
                internalList.setOverTotal(internalPeople-internalTotal);
                internalList.setTypeDetail(internalDetail);
            }else if (key.equals("consists")){
                consistsList.setPrepareTotal(internalTotal);
                consistsList.setActualNum(internalPeople);
                consistsList.setOverTotal(internalPeople-internalTotal);
                consistsList.setTypeDetail(internalDetail);
            }else if (key.equals("sends")){
                sendList.setPrepareTotal(internalTotal);
                sendList.setActualNum(internalPeople);
                sendList.setOverTotal(internalPeople-internalTotal);
                sendList.setTypeDetail(internalDetail);
            }else if (key.equals("careers")){
                careerList.setPrepareTotal(internalTotal);
                careerList.setActualNum(internalPeople);
                careerList.setOverTotal(internalPeople-internalTotal);
                careerList.setTypeDetail(internalDetail);
            }
        }
        orgAdjustVo.setPrepareTotal(prepareTotal);
        orgAdjustVo.setActualNum(actualNum);
        orgAdjustVo.setOverTotal(actualNum-prepareTotal);
        orgAdjustVo.setInternalList(internalList);
        orgAdjustVo.setConsistsList(consistsList);
        orgAdjustVo.setSendList(sendList);
        orgAdjustVo.setCareerList(careerList);
        return orgAdjustVo;
    }

    @Override
    public InstitutionDetailVo queryDetail(String orgId,String officeId,String departmentId,String tempVersionId) {
        InstitutionDetailVo institutionDetailVo = new InstitutionDetailVo();
        List<OrgEntity> childOrgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",orgId));//下级机构数据
        OrgEntity orgEntity = orgDao.selectById(orgId);
        OrgEntity nowSelectOrg = new OrgEntity();
        if (StringUtils.isNotBlank(orgId)&&StringUtils.isBlank(officeId)&&StringUtils.isBlank(departmentId)){
            nowSelectOrg = orgEntity;
        }else if (Objects.nonNull(orgId)&&Objects.nonNull(officeId)){
            nowSelectOrg = orgDao.selectById(officeId);
        }

        if (Objects.isNull(nowSelectOrg) || Objects.isNull(nowSelectOrg.getId())){
            return institutionDetailVo;
        }
        //所选机构最低配额

        // 选择机构作为原机构
        List<OrganPlanEntity> fromChange = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>()
                .eq("temp_version_id", tempVersionId)
                .eq("from_org_id",nowSelectOrg.getId()));

        // 选择机构作为目标机构
        List<OrganPlanEntity> toChange = organPlanDao.selectList(new QueryWrapper<OrganPlanEntity>()
                .eq("temp_version_id", tempVersionId)
                .eq("to_org_id",nowSelectOrg.getId()));

        Integer organizationAdmin = nowSelectOrg.getOrganizationAdmin();
        Integer organizationSingle = nowSelectOrg.getOrganizationSingle();
        Integer organizationCause = nowSelectOrg.getOrganizationCause();
        Integer organizationWork = nowSelectOrg.getOrganizationWork();

        // 作为原机构时，在原来的基础上增加变化量
        for (OrganPlanEntity organPlanEntity : fromChange) {
            if (Objects.equals(organPlanEntity.getOrganType(),OrganType.ADMIN.getCode())){
                organizationAdmin += organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(),OrganType.SINGLE.getCode())){
                organizationSingle += organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(), OrganType.CAUSE.getCode())){
                organizationCause += organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(), OrganType.WORK.getCode())){
                organizationWork += organPlanEntity.getChangeNum();
            }
        }

        // 作为目标机构时，在原来的基础上减少变化量
        for (OrganPlanEntity organPlanEntity : toChange) {
            if (Objects.equals(organPlanEntity.getOrganType(),OrganType.ADMIN.getCode())){
                organizationAdmin -= organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(),OrganType.SINGLE.getCode())){
                organizationSingle -= organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(), OrganType.CAUSE.getCode())){
                organizationCause -= organPlanEntity.getChangeNum();
            }else if (Objects.equals(organPlanEntity.getOrganType(), OrganType.WORK.getCode())){
                organizationWork -= organPlanEntity.getChangeNum();
            }
        }

        institutionDetailVo.setOrgAdmin(organizationAdmin);
        institutionDetailVo.setOrgCause(organizationCause);
        institutionDetailVo.setOrgSingle(organizationSingle);
        institutionDetailVo.setOrgWork(organizationWork);
        institutionDetailVo.setOrgPrepareTotal(organizationAdmin+ organizationCause + organizationSingle + organizationWork);
        //所选机构目前状态
        InstitutionDetailVo childOrgCateCount = getChildOrgCateCount(nowSelectOrg,tempVersionId);
        institutionDetailVo.setOrgAdminNow(childOrgCateCount.getOrgAdminNow());
        institutionDetailVo.setOrgCauseNow(childOrgCateCount.getOrgCauseNow());
        institutionDetailVo.setOrgSingleNow(childOrgCateCount.getOrgSingleNow());
        institutionDetailVo.setOrgWorkNow(childOrgCateCount.getOrgWorkNow());
        institutionDetailVo.setOrgNowTotal(childOrgCateCount.getOrgAdminNow()+childOrgCateCount.getOrgCauseNow()+childOrgCateCount.getOrgSingleNow()+childOrgCateCount.getOrgWorkNow());

        //判断是否有下级 顶部下拉框数据
        if (null!=childOrgList&&childOrgList.size()>0){//有下级
            institutionDetailVo.setChildOrg(childOrgList);
        }
        //科室数据
        if (Objects.nonNull(officeId)){//处室id不为null 展示科室数据
            List<OrgEntity> departmentList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",officeId));
            List<OrgPeopleVo> orgDetails = new ArrayList<>();
            for (OrgEntity department : departmentList) {
                OrgPeopleVo orgDetail = new OrgPeopleVo();
                if (null==department.getOrganizationAdmin()) {
                    department.setOrganizationAdmin(0);
                }
                if (null==department.getOrganizationSingle()) {
                    department.setOrganizationSingle(0);
                }
                if (null==department.getOrganizationCause()) {
                    department.setOrganizationCause(0);
                }
                if (null==department.getOrganizationWork()) {
                    department.setOrganizationWork(0);
                }
                Integer prepareTotal = department.getOrganizationAdmin()+department.getOrganizationCause()+department.getOrganizationSingle()+department.getOrganizationWork();
                List<String> status = new ArrayList();
                status.add(PersonStatus.OK.getCode());
                status.add(PersonStatus.HIGH.getCode());
                Integer actTotal = personDao.selectList(new QueryWrapper<PersonEntity>().eq("org_id",department.getId()).in("status",status)).size();
                orgDetail.setOrgId(department.getId());
                orgDetail.setOrgName(department.getOrgName());
                orgDetail.setPrepareTotal(prepareTotal);
                orgDetail.setActualNum(actTotal);
                orgDetail.setOverTotal(actTotal-prepareTotal);
                orgDetails.add(orgDetail);
            }
            institutionDetailVo.setDepartmentDetail(orgDetails);
        }

        return institutionDetailVo;
    }

    // 获取自身和下属机构的职务大类人数
    public InstitutionDetailVo getChildOrgCateCount(OrgEntity orgEntity,String tempVersionId){
        //当前所选机构的人员

        InstitutionDetailVo institutionDetailVo = orgDao.queryPostCateCount(orgEntity.getId(),PersonStatus.OK.getCode(),PersonStatus.HIGH.getCode());
        //调走的人员
        List<PersonPlanEntity> fromOrgList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("from_org_id", orgEntity.getId()).eq("temp_version_id",tempVersionId));
        Integer orgAdminChange = 0;
        Integer orgSingleChange = 0;
        Integer orgWorkChange = 0;
        Integer orgCauseChange = 0;
        for (PersonPlanEntity personPlan : fromOrgList) {//详细各个职位的变化数
            PersonEntity personEntity = personDao.selectById(personPlan.getPersonId());//变化的人员信息
            if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.ADMIN.getCode())){
                orgAdminChange = orgAdminChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.SINGLE.getCode())){
                orgSingleChange = orgSingleChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.WORK.getCode())){
                orgWorkChange = orgWorkChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.CAUSE.getCode())){
                orgCauseChange = orgCauseChange+1;
            }
        }
        institutionDetailVo.setOrgAdminNow(institutionDetailVo.getOrgAdminNow()-orgAdminChange);
        institutionDetailVo.setOrgSingleNow(institutionDetailVo.getOrgSingleNow()-orgSingleChange);
        institutionDetailVo.setOrgWorkNow(institutionDetailVo.getOrgWorkNow()-orgWorkChange);
        institutionDetailVo.setOrgCauseNow(institutionDetailVo.getOrgCauseNow()-orgCauseChange);
        //调来的人员
        List<PersonPlanEntity> toOrgList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("to_org_id", orgEntity.getId()).eq("temp_version_id",tempVersionId));
        Integer toOrgAdminChange = 0;
        Integer toOrgSingleChange = 0;
        Integer toOrgWorkChange = 0;
        Integer toOrgCauseChange = 0;
        for (PersonPlanEntity personPlan : toOrgList) {//详细各个职位的变化数
            PersonEntity personEntity = personDao.selectById(personPlan.getPersonId());//变化的人员信息
            if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.ADMIN.getCode())){
                toOrgAdminChange = orgAdminChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.SINGLE.getCode())){
                toOrgSingleChange = orgSingleChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.WORK.getCode())){
                toOrgWorkChange = orgWorkChange+1;
            }else if (Objects.equals(personEntity.getPostBigCateCode(),OrganType.CAUSE.getCode())){
                toOrgCauseChange = orgCauseChange+1;
            }
        }
        institutionDetailVo.setOrgAdminNow(institutionDetailVo.getOrgAdminNow()+toOrgAdminChange);
        institutionDetailVo.setOrgSingleNow(institutionDetailVo.getOrgSingleNow()+toOrgSingleChange);
        institutionDetailVo.setOrgWorkNow(institutionDetailVo.getOrgWorkNow()+toOrgWorkChange);
        institutionDetailVo.setOrgCauseNow(institutionDetailVo.getOrgCauseNow()+toOrgCauseChange);
        int orgAdminNow = institutionDetailVo.getOrgAdminNow();
        int orgSingleNow = institutionDetailVo.getOrgSingleNow();
        int orgCauseNow = institutionDetailVo.getOrgCauseNow();
        int orgWorkNow = institutionDetailVo.getOrgWorkNow();
        List<OrgEntity> childOrgs = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",orgEntity.getId()));
        if (CollectionUtils.isEmpty(childOrgs)){
            return institutionDetailVo;
        }else {//递归
            for (OrgEntity childOrg : childOrgs) {
                InstitutionDetailVo childOrgCateCount = getChildOrgCateCount(childOrg,tempVersionId);
                orgAdminNow = orgAdminNow + childOrgCateCount.getOrgAdminNow();
                orgSingleNow = orgSingleNow + childOrgCateCount.getOrgSingleNow();
                orgCauseNow = orgCauseNow + childOrgCateCount.getOrgCauseNow();
                orgWorkNow = orgWorkNow + childOrgCateCount.getOrgWorkNow();
            }
            institutionDetailVo.setOrgAdminNow(orgAdminNow);
            institutionDetailVo.setOrgSingleNow(orgSingleNow);
            institutionDetailVo.setOrgCauseNow(orgCauseNow);
            institutionDetailVo.setOrgWorkNow(orgWorkNow);
        }
        return institutionDetailVo;
    }

    @Override
    public List<OrgEntity> queryOrg(String orgId,String orgName) {
        OrgEntity orgEntity = orgDao.selectById(orgId);
        List<OrgEntity> orgList = orgDao.queryOrgByOrgNameLike(orgEntity.getPid(),orgName);//所选二级机构同级机构
        return orgList;
    }

    @Override
    public List<OrgEntity> queryOfficeOrg(String orgId, String orgName) {
        List<OrgEntity> officeOrgList = orgDao.queryOrgByOrgNameLike(orgId, orgName);
        return officeOrgList;
    }

    @Override
    public InstitutionDetailVo queryOrgPeopleDetail(String orgId, String officeId, String departmentId,String tempId) {
        InstitutionDetailVo institutionDetailVo = new InstitutionDetailVo();
        //二级机构人员名单
        List<OrgPeopleDetailVo> orgPeopleDetailList = getOrgChangedPeoples(tempId, orgId);
        institutionDetailVo.setOrgPeopleList(orgPeopleDetailList);

        //处室机构人员名单
        if (StringUtils.isBlank(officeId)){
            //全部
//            List<String> orgLevel = new ArrayList<>();
//            orgLevel.add(MechanismLevel.DIVISION.getCode());
//            orgLevel.add(MechanismLevel.DIVISIONDEPUTY.getCode());
            List<OrgEntity> officeOrgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",orgId));
            List<OrgPeopleDetailVo> officeOrgPeopleList = new ArrayList<>();
            for (OrgEntity officeOrg : officeOrgList) {
                officeOrgPeopleList.addAll(getOrgChangedPeoples(tempId,officeOrg.getId()));
            }
            institutionDetailVo.setOfficeOrgPeopleList(officeOrgPeopleList);
        }else {
            List<OrgPeopleDetailVo> officeOrgPeopleList = getOrgChangedPeoples(tempId,officeId);
            institutionDetailVo.setOfficeOrgPeopleList(officeOrgPeopleList);
        }
        //科室机构人员名单
//        List<String> officeOrgLevel = new ArrayList<>();
//        officeOrgLevel.add(MechanismLevel.DIVISION.getCode());
//        officeOrgLevel.add(MechanismLevel.DIVISIONDEPUTY.getCode());
//        List<String> departmentOrgLevel = new ArrayList<>();
//        departmentOrgLevel.add(MechanismLevel.DEPARTMENT.getCode());
//        departmentOrgLevel.add(MechanismLevel.DEPARTMENTDEPUTY.getCode());
        if (StringUtils.isBlank(officeId)){
            //全部
            List<OrgPeopleDetailVo> departmentOrgPeopleList = new ArrayList<>();
            List<OrgEntity> officeOrgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",orgId));
            for (OrgEntity officeOrg : officeOrgList) {//循环处室
                List<OrgEntity> departmentOrgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid",officeOrg.getId()));//科室集合
                for (OrgEntity departmentOrg : departmentOrgList) {//循环科室
                    List<OrgPeopleDetailVo> departmentOrgPeoples = getOrgChangedPeoples(tempId,departmentOrg.getId());
                    departmentOrgPeopleList.addAll(departmentOrgPeoples);
                }
            }
            institutionDetailVo.setDepartmentOrgPeopleList(departmentOrgPeopleList);
        }else if(StringUtils.isNotBlank(officeId)&&StringUtils.isBlank(departmentId)){
            //所选处室下面科室的人员
            List<OrgPeopleDetailVo> departmentOrgPeopleList = new ArrayList<>();
            List<OrgEntity> departmentOrgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", officeId));
            for (OrgEntity departmentOrg : departmentOrgList) {
                List<OrgPeopleDetailVo> departmentOrgPeoples = getOrgChangedPeoples(tempId,departmentOrg.getId());
                departmentOrgPeopleList.addAll(departmentOrgPeoples);
            }
            institutionDetailVo.setDepartmentOrgPeopleList(departmentOrgPeopleList);
        }else {
            List<OrgPeopleDetailVo> departmentOrgPeopleList = getOrgChangedPeoples(tempId,departmentId);
            institutionDetailVo.setDepartmentOrgPeopleList(departmentOrgPeopleList);
        }

        return institutionDetailVo;
    }


    public List<OrgPeopleDetailVo> getOrgChangedPeoples(String tempId,String orgId){
        List<OrgPeopleDetailVo> orgPeopleDetailList = personDao.queryOrgPeople(orgId,PersonStatus.OK.getCode(),PersonStatus.HIGH.getCode());
        List<PersonPlanEntity> personPlanList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("temp_version_id", tempId).eq("from_org_id",orgId));
        if (CollectionUtils.isNotEmpty(personPlanList)){//该机构有调走的人员
            for (PersonPlanEntity personPlanEntity : personPlanList) {
                for (int i=0;i<orgPeopleDetailList.size();i++){//循环原机构人员 将调走的人员删除
                    OrgPeopleDetailVo orgPeopleDetailVo = orgPeopleDetailList.get(i);
                    if (orgPeopleDetailList.get(i).getId().equals(personPlanEntity.getPersonId())){
                        orgPeopleDetailList.remove(orgPeopleDetailVo);
                    }
                }
            }
        }
        List<PersonPlanEntity> personPlanAddList = personPlanDao.selectList(new QueryWrapper<PersonPlanEntity>().eq("temp_version_id", tempId).eq("to_org_id",orgId));
        if (CollectionUtils.isNotEmpty(personPlanAddList)){//该机构有调来的人员
            for (PersonPlanEntity personPlanEntity : personPlanAddList) {
                PersonEntity personEntity = personDao.selectById(personPlanEntity.getPersonId());
                OrgPeopleDetailVo orgPeopleDetailVo = new OrgPeopleDetailVo();
                BeanUtils.copyProperties(personEntity,orgPeopleDetailVo);
                orgPeopleDetailVo.setOrgId(personPlanEntity.getToOrgId());
                orgPeopleDetailList.add(orgPeopleDetailVo);
            }
        }

        return orgPeopleDetailList;
    }

    //获取该机构及该机构下面所有机构的人数
    int getOrgPersonTotal(String orgId,Map<String, List<PersonEntity>> orgId2Map,Map<String, List<OrgEntity>> pid2Map){

        int total = 0;
        int currentTotal = Objects.nonNull(orgId2Map.get(orgId)) ? orgId2Map.get(orgId).size() : 0;//当前机构人数
        total += currentTotal;

        List<OrgEntity> childOrgList = pid2Map.get(orgId);//下属机构
        if (Objects.nonNull(childOrgList)){//机构有下级
            for (OrgEntity childOrg : childOrgList) {
                total += getOrgPersonTotal(childOrg.getId(),orgId2Map,pid2Map);
            }
        }

        return total;
    }

    @Override
    public BarEchartsVo queryBarEchartsData(String orgId) {
        BarEchartsVo barEchartsVo = new BarEchartsVo();

        List<OrgEntity> orgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", orgId).orderByDesc("create_time"));//市公安局下属机构

        // 正常人员与高配人员
        List<PersonEntity> okAndHighPerson = personDao.selectList(new QueryWrapper<PersonEntity>().in("status", Arrays.asList(PersonStatus.OK.getCode(), PersonStatus.HIGH.getCode())));

        okAndHighPerson = okAndHighPerson.stream().filter(o -> Objects.nonNull(o.getOrgId())).collect(Collectors.toList());

        // 人员 根据orgId分组
        Map<String, List<PersonEntity>> orgId2Map = okAndHighPerson.stream().collect(Collectors.groupingBy(PersonEntity::getOrgId));

        List<OrgEntity> orgEntityList = orgDao.selectList(new QueryWrapper<>());
        Map<String, List<OrgEntity>> pid2Map = orgEntityList.stream().collect(Collectors.groupingBy(OrgEntity::getPid));

        for (OrgEntity org : orgList) {//二级机构
            barEchartsVo.getOrgIdList().add(org.getId());
            barEchartsVo.getOrgDataList().add(org.getOrgName());
            barEchartsVo.getAdminDataList().add(org.getOrganizationAdmin());
            barEchartsVo.getSingleDataList().add(org.getOrganizationSingle());
            barEchartsVo.getWorkDataList().add(org.getOrganizationWork());
            barEchartsVo.getCauseDataList().add(org.getOrganizationCause());
            //查询该机构四大类职务人数
            InstitutionDetailVo orgCateCount = getOrgCateCount(org, orgId2Map,pid2Map);
            barEchartsVo.getAdminPersonDataList().add(orgCateCount.getOrgAdminNow());
            barEchartsVo.getSinglePersonDataList().add(orgCateCount.getOrgSingleNow());
            barEchartsVo.getWorkPersonDataList().add(orgCateCount.getOrgWorkNow());
            barEchartsVo.getCausePersonDataList().add(orgCateCount.getOrgCauseNow());
        }

        return barEchartsVo;
    }


    @Override
    public void exportExcel(HttpServletResponse response, String orgId) {
        OrgEntity orgEntity = orgDao.selectById(orgId);
        List<OrgEntity> orgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", orgId).orderByAsc("create_time"));
        ExcelUtil<OrgEntity> util = new ExcelUtil<>(OrgEntity.class);
        util.exportExcel(response, orgList, "机构预设编制",orgEntity.getOrgName()+"下属机构预设编制数");
    }

    @Override
    public void exportPersonExcel(HttpServletResponse response, String orgId) {
        OrgEntity org = orgDao.selectById(orgId);
        List<OrgEntity> orgList = orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", orgId).orderByAsc("create_time"));
        List<InstitutionDetailVo> orgPersonList = new ArrayList<>();
        // 正常人员与高配人员
        List<PersonEntity> okAndHighPerson = personDao.selectList(new QueryWrapper<PersonEntity>().in("status", Arrays.asList(PersonStatus.OK.getCode(), PersonStatus.HIGH.getCode())));

        okAndHighPerson = okAndHighPerson.stream().filter(o -> Objects.nonNull(o.getOrgId())).collect(Collectors.toList());

        // 人员 根据orgId分组
        Map<String, List<PersonEntity>> orgId2Map = okAndHighPerson.stream().collect(Collectors.groupingBy(PersonEntity::getOrgId));

        List<OrgEntity> orgEntityList = orgDao.selectList(new QueryWrapper<OrgEntity>().orderByAsc("create_time"));
        Map<String, List<OrgEntity>> pid2Map = orgEntityList.stream().collect(Collectors.groupingBy(OrgEntity::getPid));
        for (OrgEntity orgEntity : orgList) {
            InstitutionDetailVo orgCateCount = getOrgCateCount(orgEntity,orgId2Map,pid2Map);
            orgPersonList.add(orgCateCount);
        }
        ExcelUtil<InstitutionDetailVo> util = new ExcelUtil<>(InstitutionDetailVo.class);
        util.exportExcel(response, orgPersonList, "机构实配编制人数",org.getOrgName()+"下属机构实配编制人数");
    }

    @Override
    public void exportYearExcel(HttpServletResponse response, String orgId) {
        OrgEntity org = orgDao.selectById(orgId);
        List<OrgDetailYear> orgDetailYears = orgDetailYearDao.queryBarEchartsData(orgId);
        ExcelUtil<OrgDetailYear> util = new ExcelUtil<>(OrgDetailYear.class);
        util.hideColumn("adminPerson", "singlePerson","workPerson","causePerson");
        util.exportExcel(response, orgDetailYears, "年度预设编制数",org.getOrgName()+"年度预设编制数");
    }

    @Override
    public void exportPersonYearExcel(HttpServletResponse response, String orgId) {
        OrgEntity org = orgDao.selectById(orgId);
        List<OrgDetailYear> orgDetailYears = orgDetailYearDao.queryBarEchartsData(orgId);
        ExcelUtil<OrgDetailYear> util = new ExcelUtil<>(OrgDetailYear.class);
        util.hideColumn("admin", "single","work","cause");
        util.exportExcel(response, orgDetailYears, "年度实配人数",org.getOrgName()+"年度实配人数");
    }

    @Override
    public Boolean selectRule(SelectRuleVo selectRuleVo) {
        OrgEntity orgEntity = orgDao.selectById(selectRuleVo.getPid());
        if (Objects.isNull(orgEntity)){
            return true;
        }
        if (selectRuleVo.getAddFlag().equals("0")){
            orgEntity = orgDao.selectById(orgEntity.getPid());
        }
        if (Objects.nonNull(orgEntity)&&StringUtils.isNotBlank(selectRuleVo.getOrgLevel())&&StringUtils.isNotBlank(orgEntity.getOrgLevel())){
            if (Integer.parseInt(selectRuleVo.getOrgLevel())>Integer.parseInt(orgEntity.getOrgLevel())){
                return true;
            }else {
                return false;
            }
        }
        return true;
    }


    //获取机构和下属机构的职务人数（没有人员调整，统计图用）
    public InstitutionDetailVo getOrgCateCount(OrgEntity orgEntity, Map<String, List<PersonEntity>> orgId2Map,Map<String, List<OrgEntity>> pid2Map){
        //当前所选机构的人员
        List<PersonEntity> personEntities = orgId2Map.get(orgEntity.getId());

        InstitutionDetailVo institutionDetailVo = new InstitutionDetailVo();


        int orgAdminNow = 0;
        int orgSingleNow = 0;
        int orgCauseNow = 0;
        int orgWorkNow = 0;
        if (CollectionUtils.isNotEmpty(personEntities)
                && CollectionUtils.isNotEmpty(personEntities.stream().filter(p -> Objects.nonNull(p.getPostBigCateCode())).collect(Collectors.toList()))){

            personEntities = personEntities.stream().filter(p -> Objects.nonNull(p.getPostBigCateCode())).collect(Collectors.toList());

            Map<String, List<PersonEntity>> bigCateCode2Map = personEntities.stream().collect(Collectors.groupingBy(PersonEntity::getPostBigCateCode));
            orgAdminNow = Objects.nonNull(bigCateCode2Map.get(OrganType.ADMIN.getCode())) ? bigCateCode2Map.get(OrganType.ADMIN.getCode()).size() : 0;
            orgSingleNow = Objects.nonNull(bigCateCode2Map.get(OrganType.SINGLE.getCode())) ? bigCateCode2Map.get(OrganType.SINGLE.getCode()).size() : 0;
            orgCauseNow = Objects.nonNull(bigCateCode2Map.get(OrganType.CAUSE.getCode())) ? bigCateCode2Map.get(OrganType.CAUSE.getCode()).size() : 0;
            orgWorkNow = Objects.nonNull(bigCateCode2Map.get(OrganType.WORK.getCode())) ? bigCateCode2Map.get(OrganType.WORK.getCode()).size() : 0;

        }

        institutionDetailVo.setOrgAdminNow(orgAdminNow);
        institutionDetailVo.setOrgSingleNow(orgSingleNow);
        institutionDetailVo.setOrgCauseNow(orgCauseNow);
        institutionDetailVo.setOrgWorkNow(orgWorkNow);


        List<OrgEntity> childOrgs = pid2Map.get(orgEntity.getId());

        if (CollectionUtils.isEmpty(childOrgs)){
            institutionDetailVo.setOrgName(orgEntity.getOrgName());
            return institutionDetailVo;
        }else {//递归
            for (OrgEntity childOrg : childOrgs) {
                InstitutionDetailVo childOrgCateCount = getOrgCateCount(childOrg,orgId2Map,pid2Map);
                orgAdminNow = orgAdminNow + childOrgCateCount.getOrgAdminNow();
                orgSingleNow = orgSingleNow + childOrgCateCount.getOrgSingleNow();
                orgCauseNow = orgCauseNow + childOrgCateCount.getOrgCauseNow();
                orgWorkNow = orgWorkNow + childOrgCateCount.getOrgWorkNow();
            }
            institutionDetailVo.setOrgName(orgEntity.getOrgName());
            institutionDetailVo.setOrgAdminNow(orgAdminNow);
            institutionDetailVo.setOrgSingleNow(orgSingleNow);
            institutionDetailVo.setOrgCauseNow(orgCauseNow);
            institutionDetailVo.setOrgWorkNow(orgWorkNow);
        }
        return institutionDetailVo;
    }

    //查询济南公安局的机构id以及名字
    public HashMap<String,String> getJNOrg(){
        HashMap<String, String> result = new HashMap<>();

        // 查询一级机构 济南编制办公室
        OrgEntity firstOrg = orgDao.selectOne(new QueryWrapper<OrgEntity>().eq("pid", "0"));

        // 济南公安局
        OrgEntity jnOrg = orgDao.selectOne(new QueryWrapper<OrgEntity>().eq("pid", firstOrg.getId()));

        result.put("orgId",jnOrg.getId());
        result.put("orgName", jnOrg.getOrgName());

        return result;
    }

    public void exportCustom(HttpServletResponse response, ExportCustomQuery exportCustomQuery){

        Map<String, OrgTreeVo> orgId2Map = getOrgId2Map(exportCustomQuery.getOrgId());

        List<PersonEntity> personEntityList;

        if (Objects.nonNull(exportCustomQuery.getStartAge()) || Objects.nonNull(exportCustomQuery.getEndAge())) {

            int endYear = Objects.nonNull(exportCustomQuery.getStartAge()) ?
                    LocalDate.now().minusYears(exportCustomQuery.getStartAge()).getYear() : LocalDate.now().getYear();
            int startYear = Objects.nonNull(exportCustomQuery.getEndAge()) ?
                    LocalDate.now().minusYears(exportCustomQuery.getEndAge()).getYear() : LocalDate.now().minusYears(200).getYear();

            int month = LocalDate.now().getMonth().getValue();
            int day = LocalDate.now().getDayOfMonth();

            String endYearStr = endYear + "" + month + (day < 10 ? "0" + day : day);
            String startYearStr = startYear + "" + month + (day < 10 ? "0" + day : day);

            personEntityList = personDao.selectList(new QueryWrapper<PersonEntity>()
                    .in(CollectionUtils.isNotEmpty(orgId2Map), "org_id", orgId2Map.keySet())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getName()), "name", exportCustomQuery.getName())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getIdentityNo()), "identity_no", exportCustomQuery.getIdentityNo())
                    .eq(StringUtils.isNotBlank(exportCustomQuery.getStatus()), "status", exportCustomQuery.getStatus())
                    .eq(StringUtils.isNotBlank(exportCustomQuery.getSex()), "sex", exportCustomQuery.getSex())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getEducation()), "education", exportCustomQuery.getEducation())
                    .in(StringUtils.isNotBlank(exportCustomQuery.getLeaderType()), "leader_type", exportCustomQuery.getLeaderType())
                    .ge("substring( identity_no, 7, 4 )", startYearStr).le("substring( identity_no, 7, 4 )", endYearStr)
                    .orderByAsc("org_id"));

        }else {
            personEntityList = personDao.selectList(new QueryWrapper<PersonEntity>()
                    .in(CollectionUtils.isNotEmpty(orgId2Map), "org_id", orgId2Map.keySet())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getName()), "name", exportCustomQuery.getName())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getIdentityNo()), "identity_no", exportCustomQuery.getIdentityNo())
                    .eq(StringUtils.isNotBlank(exportCustomQuery.getStatus()), "status", exportCustomQuery.getStatus())
                    .eq(StringUtils.isNotBlank(exportCustomQuery.getSex()), "sex", exportCustomQuery.getSex())
                    .like(StringUtils.isNotBlank(exportCustomQuery.getEducation()), "education", exportCustomQuery.getEducation())
                    .in(StringUtils.isNotBlank(exportCustomQuery.getLeaderType()), "leader_type", exportCustomQuery.getLeaderType())
                    .orderByAsc("org_id"));
        }

        if (CollectionUtils.isEmpty(personEntityList)){
            ExcelUtil<ExportCustomVo> util = new ExcelUtil<>(ExportCustomVo.class);
            util.exportExcel(response, new ArrayList<>(), "人员信息","");
            return;
        }
        List<ExportCustomVo> exportCustomVoList = new ArrayList<>();
        for (PersonEntity personEntity : personEntityList) {
            ExportCustomVo exportCustomVo = new ExportCustomVo();
            BeanUtils.copyProperties(personEntity,exportCustomVo);
            exportCustomVoList.add(exportCustomVo);
        }

        List<SysDictData> sysDictData = sysDictDataMapper.selectList(new QueryWrapper<>());
        Map<String, List<SysDictData>> dictType2Map = sysDictData.stream().collect(Collectors.groupingBy(SysDictData::getDictType));
        // 职级层次大类
        List<SysDictData> bigLevelDict = dictType2Map.get("person_level_big_level");
        Map<String, SysDictData> bigLevel2Map = bigLevelDict.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 职级层次小类
        List<SysDictData> smallLevelList = new ArrayList<>();

        for (SysDictData dictData : bigLevelDict) {
            smallLevelList.addAll(dictType2Map.get(dictData.getDictValue()));
        }
        Map<String, SysDictData> smallLevel2Map = smallLevelList.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 职务层次大类
        List<SysDictData> postBigCateCodeDict = dictType2Map.get("post_big_cate_code");
        Map<String, SysDictData> bigCate2Map = postBigCateCodeDict.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 职务层次小类
        List<SysDictData> smallCateList = new ArrayList<>();
        for (SysDictData dictData : postBigCateCodeDict) {
            if (CollectionUtils.isNotEmpty(dictType2Map.get(dictData.getDictValue()))){
                smallCateList.addAll(dictType2Map.get(dictData.getDictValue()));
            }
        }
        Map<String, SysDictData> smallCate2Map = smallCateList.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 人员状态
        Map<String, SysDictData> personStatus2Map = dictType2Map.get("person_status").stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 人员状态
        Map<String, SysDictData> sex2Map = dictType2Map.get("sys_user_sex").stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 领导类型
        Map<String, SysDictData> leaderType2Map = dictType2Map.get("leader_type").stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        // 领导类型
        Map<String, SysDictData> personTitle2Map = dictType2Map.get("person_title_type").stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));

        exportCustomVoList.forEach(s -> {

            // 所在部门
            if (StringUtils.isNotBlank(s.getOrgId())){
                s.setOrgName(Objects.nonNull(orgId2Map.get(s.getOrgId())) ? orgId2Map.get(s.getOrgId()).getOrgName() : "");
            }

            // 计算出生日期、年龄
            if (StringUtils.isNotBlank(s.getIdentityNo())){
                s.setBirthDate(IdCardNumberMethod.getBirthFromIdCard(s.getIdentityNo()));
                s.setAge(IdCardNumberMethod.getAgeForIdCard(s.getIdentityNo()));
            }
            // 职级层次大类
            if (StringUtils.isNotBlank(s.getJobLevel())){
                s.setJobLevel(Objects.nonNull(bigLevel2Map.get(s.getJobLevel())) ? bigLevel2Map.get(s.getJobLevel()).getDictLabel() : "");
            }
            // 职级层次小类
            if (StringUtils.isNotBlank(s.getJobLevelSmall())){
                s.setJobLevelSmall(Objects.nonNull(smallLevel2Map.get(s.getJobLevelSmall())) ? smallLevel2Map.get(s.getJobLevelSmall()).getDictLabel() : "");
            }
            // 职务层次大类
            if (StringUtils.isNotBlank(s.getPostBigCateCode())){
                s.setPostBigCateCode(Objects.nonNull(bigCate2Map.get(s.getPostBigCateCode())) ? bigCate2Map.get(s.getPostBigCateCode()).getDictLabel() : "");
            }
            // 职务层次小类
            if (StringUtils.isNotBlank(s.getPostSmallCateCode())){
                s.setPostSmallCateCode(Objects.nonNull(smallCate2Map.get(s.getPostSmallCateCode())) ? smallCate2Map.get(s.getPostSmallCateCode()).getDictLabel() : "");
            }
            // 人员状态
            if (StringUtils.isNotBlank(s.getStatus())){
                s.setStatus(Objects.nonNull(personStatus2Map.get(s.getStatus())) ? personStatus2Map.get(s.getStatus()).getDictLabel() : "");
            }
            // 领导类型
            if (StringUtils.isNotBlank(s.getLeaderType())){
                s.setLeaderType(Objects.nonNull(leaderType2Map.get(s.getLeaderType())) ? leaderType2Map.get(s.getLeaderType()).getDictLabel() : "");
            }

            // 警衔
            if (StringUtils.isNotBlank(s.getJobTitle())){
                s.setJobTitle(Objects.nonNull(personTitle2Map.get(s.getJobTitle())) ? personTitle2Map.get(s.getJobTitle()).getDictLabel() : "");
            }

            // 性别
            if (StringUtils.isNotBlank(s.getSex())){
                s.setSex(Objects.nonNull(sex2Map.get(s.getSex())) ? sex2Map.get(s.getSex()).getDictLabel() : "");
            }

        });

        ExcelUtil<ExportCustomVo> util = new ExcelUtil<>(ExportCustomVo.class);

        util.hideColumn(exportCustomQuery.getHideColumn().split(","));

        util.exportExcel(response, exportCustomVoList, "人员信息","");
    }

    public Map<String, OrgTreeVo> getOrgId2Map(String orgId) {

        // 默认为济南市公安局
        if (StringUtils.isBlank(orgId)) {
            orgId = "1584019929357635586";
        }

        OrgEntity orgEntity = orgDao.selectById(orgId);
        List<OrgEntity> allOrg = orgDao.selectList(new QueryWrapper<>());
        // 获取改机构下面的所有的机构
        List<OrgTreeVo> orgList = TreeUtils.getAllOrgScreen(orgId, allOrg);
        OrgTreeVo orgTreeVo = new OrgTreeVo();
        BeanUtils.copyProperties(orgEntity,orgTreeVo);
        orgList.add(orgTreeVo);

        return orgList.stream().collect(Collectors.toMap(OrgTreeVo::getId, Function.identity()));
    }

    public List<OrgEntity> getSameLevelOrg(String orgId) {
        OrgEntity orgEntity = orgDao.selectById(orgId);
        return orgDao.selectList(new QueryWrapper<OrgEntity>().eq("pid", orgEntity.getPid()));
    }

}
